package ecom.shell;

import java.io.IOException;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import shell.Shell;
import shell.command.ShellCommandImpl;
import shell.command.ShellContext;
import ecom.entity.AccountRemote;
import ecom.ejb.AdminRemote;
import ecom.ejb.CustomerRemote;
import ecom.ejb.EuroConverterRemote;
import ecom.ejb.EuroConverterRemote.Devise;
import exceptions.IdentifiantInvalide;
import exceptions.InstanceInvalide;

/**
 * @author François Haurit
 * @version 1.0
 */
public final class AccountCommandImpl extends ShellCommandImpl {

    public AccountCommandImpl(ShellContext context) {
        super(context);
    }

    @Override
    public String getName() {
        return "account";
    }

    @Override
    public String getUsage() {
        return "account [ -create <iban> <solde> ]";
    }

    @Override
    public String getShortDescription() {
        return "Get list of all accounts";
    }

    @Override
    public void execute(final String ligneDeCommande, final PrintStream out,
            final PrintStream err) {
        String ligneDeCommandeMEF = ligneDeCommande.trim();
        // Création
        Pattern patternCreate = Pattern.compile("^-create\\s(\\w{34})\\s(\\d+)$");

        // Suppression
        Pattern patternDelete = Pattern.compile("^-delete\\s(\\w{34})$");

        Document dom = null;
        Element root = null;
        StringBuilder texte = null;
        boolean erreur = false;

        if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.TEXT_MIMETYPE)) {
            // Si TEXTE
            texte = new StringBuilder();
        } else if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.XML_MIMETYPE)) {
            //Si XML
            try {
                dom = Output.getNewDocument();
                root = dom.createElement(this.getName() + "Command");
                dom.appendChild(root);
            } catch (final ParserConfigurationException e) {
                err.println(e.getMessage());
            }
        }

        // Aucun argument -> Liste
        if (ligneDeCommandeMEF.equals("")) {
            out.println("Liste de tous les comptes");

            List<AccountRemote> comptesRemote = ((CustomerRemote) this.getContexte().getVar("customer")).listAccounts();

            if (comptesRemote != null) {
                out.println("Affichage des comptes");

                AccountRemote cr = null;
                Iterator<AccountRemote> it = comptesRemote.iterator();
                while (it.hasNext()) {
                    cr = it.next();

                    if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.TEXT_MIMETYPE)) {
                        /*
                         * Si TEXTE
                         */
                        texte.append("\t" + Output.toString( cr,(Devise) this.getContexte().getVar(EcomShellConstantes.CURRENT_CURRENCY),
                                ((EuroConverterRemote) this.getContexte().getVar(EcomShellConstantes.CONVERTER)))
                                + Shell.RETOUR_CHARIOT);
                    } else if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.XML_MIMETYPE)) {
                        /*
                         * Si XML
                         */
                        root.appendChild(Output.toXml(cr,
                                dom,
                                (Devise) this.getContexte().getVar(EcomShellConstantes.CURRENT_CURRENCY),
                                ((EuroConverterRemote) this.getContexte().getVar(EcomShellConstantes.CONVERTER))));
                    }
                }
            } else {
                out.println("Aucun compte");
            }
        } else if (patternCreate.matcher(ligneDeCommandeMEF).find()) {
            String[] arguments = ligneDeCommande.replace("-create ", "").split(
                    " ");

            try {
                out.println("Création du compte " + arguments[0]
                        + " avec le solde "
                        + Double.valueOf(arguments[1]).toString());
                out.println("user/password sont les identifiants par défaut.");

                AccountRemote compte = ((AdminRemote) this.getContexte().getVar(EcomShellConstantes.ADMIN)).createAccount(
                        arguments[0], Double.valueOf(arguments[1]), "user", "password");

                if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.TEXT_MIMETYPE)) {
                    /*
                     * Si TEXTE
                     */
                    texte.append("\t"
                            + Output.toString(
                            compte,
                            (Devise) this.getContexte().getVar(EcomShellConstantes.CURRENT_CURRENCY),
                            ((EuroConverterRemote) this.getContexte().getVar(EcomShellConstantes.CONVERTER)))
                            + Shell.RETOUR_CHARIOT);
                } else if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.XML_MIMETYPE)) {
                    /*
                     * Si XML
                     */
                    root.appendChild(Output.toXml(
                            compte,
                            dom,
                            (Devise) this.getContexte().getVar(
                            EcomShellConstantes.CURRENT_CURRENCY),
                            ((EuroConverterRemote) this.getContexte().getVar(
                            EcomShellConstantes.CONVERTER))));
                }
            } catch (final NumberFormatException e) {
                err.println(e.getMessage());
            } catch (final IdentifiantInvalide e) {
                err.println(e.getMessage());
            } catch (final InstanceInvalide e) {
                err.println(e.getMessage());
            }
        } else if (patternDelete.matcher(ligneDeCommandeMEF).find()) {
            String arguments = ligneDeCommande.replace("-delete ", "");

            out.println("Suppression du compte " + arguments);

            AccountRemote compte;
            try {
                compte = ((AdminRemote) this.getContexte().getVar(
                        EcomShellConstantes.ADMIN)).getAccount(arguments);

                System.out.println(compte);
                ((AdminRemote) this.getContexte().getVar(
                        EcomShellConstantes.ADMIN)).removeAccount(compte);
            } catch (final IdentifiantInvalide e) {
                err.println(e.getMessage());
            }
        } else {
            out.println("Usage: " + this.getUsage());
            erreur = true;
        }

        if (!erreur) {

            if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.TEXT_MIMETYPE)) {

                out.println(texte.toString());
            } else if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.XML_MIMETYPE)) {
                try {
                    out.println(Output.toString(dom));
                } catch (final IOException e) {
                    err.println(e.getMessage());
                }
            }
        }
    }
}
